package org.pearl.springboot.minio.sdk;

import io.minio.*;
import io.minio.errors.*;
import io.minio.messages.*;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.ZonedDateTime;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * Created by TD on 2021/10/19
 */
public class MinioBucketSet {
    public static void main(String[] args) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, ErrorResponseException {
        // 初始化客户端
        MinioClient minioClient =
                MinioClient.builder()
                        // minio服务端地址URL
                        .endpoint("http://localhost:9000")
                        // 用户名及密码（访问密钥/密钥）
                        .credentials("admin", "admin123")
                        .build();

/*        minioClient.setBucketEncryption(
                SetBucketEncryptionArgs.builder()
                        .bucket("my-bucketname")
                        .config(SseConfiguration.newConfigWithSseS3Rule())
                        .build());
        System.out.println("Encryption configuration of my-bucketname is set successfully");*/

        // 1. 存储桶标签
        Map<String, String> map = new HashMap<>();
        map.put("Project", "Project One");
        map.put("User", "jsmith");
        minioClient.setBucketTags(SetBucketTagsArgs.builder().bucket("my-bucketname").tags(map).build());
        Tags bucketTags = minioClient.getBucketTags(GetBucketTagsArgs.builder().bucket("my-bucketname").build());
        System.out.println(bucketTags.get().toString());

        // 2. 版本配置
        // 'my-bucketname'启用版本控制
        minioClient.setBucketVersioning(
                SetBucketVersioningArgs.builder()
                        .bucket("my-bucketname")
                        .config(new VersioningConfiguration(VersioningConfiguration.Status.ENABLED, null))
                        .build());
        System.out.println("Bucket versioning is enabled successfully");

        //  'my-bucketname'暂停版本控制
        minioClient.setBucketVersioning(
                SetBucketVersioningArgs.builder()
                        .bucket("my-bucketname")
                        .config(new VersioningConfiguration(VersioningConfiguration.Status.SUSPENDED, null))
                        .build());
        System.out.println("Bucket versioning is suspended successfully");

        // 3. 将保留模式设置为Compliance，且持续时间为100天的
        // 设置锁定对象的保留模式及时限
        ObjectLockConfiguration config =
                new ObjectLockConfiguration(RetentionMode.COMPLIANCE, new RetentionDurationDays(100));
        minioClient.setObjectLockConfiguration(
                SetObjectLockConfigurationArgs.builder()
                        .bucket("aaaaa")
                        .config(config)
                        .build());
        System.out.println("object-lock configuration is set successfully");
        // 获取锁定配置
        ObjectLockConfiguration objectLockConfiguration =
                minioClient.getObjectLockConfiguration(
                        GetObjectLockConfigurationArgs.builder()
                                .bucket("my-bucketname-in-eu-with-object-lock")
                                .build());

        System.out.println("Object-lock configuration of bucket");
        System.out.println("Mode: " + objectLockConfiguration.mode());
        System.out.println("Duration: " + objectLockConfiguration.duration());

        //4. 加密配置
/*        minioClient.setBucketEncryption(
                SetBucketEncryptionArgs.builder()
                        .bucket("my-bucketname")
                        // 设置
                        .config(SseConfiguration.newConfigWithSseS3Rule())
                        .build());
        System.out.println("Encryption configuration of my-bucketname is set successfully");
        SseConfiguration sseConfiguration =
                minioClient.getBucketEncryption(
                        GetBucketEncryptionArgs.builder().bucket("my-bucketname").build());
        if (sseConfiguration.rule() != null) {
            System.out.println("Rule SSE algorithm: " + sseConfiguration.rule().sseAlgorithm());
            if (sseConfiguration.rule().sseAlgorithm() == SseAlgorithm.AWS_KMS) {
                System.out.println("Rule KMS master key ID: " + sseConfiguration.rule().kmsMasterKeyId());
            }
        } else {
            System.out.println("No rule is set in SSE configuration.");
        }*/

        // 5. 生命周期
        List<LifecycleRule> rules = new LinkedList<>();
        // 配置生命周期规则
        rules.add(
                new LifecycleRule(
                        Status.ENABLED, // 开启状态
                        null,
                        new Expiration((ZonedDateTime) null, 365, null), // 保存365天
                        new RuleFilter("logs/"), // 目录配置
                        "rule2",
                        null,
                        null,
                        null));
        LifecycleConfiguration lifecycleConfiguration = new LifecycleConfiguration(rules);
        // 添加生命周期配置
        minioClient.setBucketLifecycle(
                SetBucketLifecycleArgs.builder().bucket("my-bucketname").config(lifecycleConfiguration).build());
        // 获取配置
        LifecycleConfiguration lifecycleConfiguration1111 =
                minioClient.getBucketLifecycle(
                        GetBucketLifecycleArgs.builder().bucket("my-bucketname").build());
        List<LifecycleRule> rules1 = lifecycleConfiguration1111.rules();
        for (int i = 0; i < rules1.size(); i++) {
            System.out.println("Lifecycle status is " + rules1.get(i).status());
            System.out.println("Lifecycle prefix is " + rules1.get(i).filter().prefix());
            System.out.println("Lifecycle expiration days is " + rules1.get(i).expiration().days());
        }

        // 6. 通知配置
        // Add a new SQS configuration.
        NotificationConfiguration notificationConfiguration = new NotificationConfiguration();
        List<QueueConfiguration> queueConfigurationList = notificationConfiguration.queueConfigurationList();
        QueueConfiguration queueConfiguration = new QueueConfiguration();
        queueConfiguration.setQueue("arn:minio:sqs::1:webhook");

        List<EventType> eventList = new LinkedList<>();
        eventList.add(EventType.OBJECT_CREATED_PUT);
        eventList.add(EventType.OBJECT_CREATED_COPY);
        queueConfiguration.setEvents(eventList);
        queueConfiguration.setPrefixRule("images");
        queueConfiguration.setSuffixRule("pg");

        queueConfigurationList.add(queueConfiguration);
        notificationConfiguration.setQueueConfigurationList(queueConfigurationList);

        // Set updated notification configuration.
        minioClient.setBucketNotification(
                SetBucketNotificationArgs.builder().bucket("my-bucketname").config(notificationConfiguration).build());
        System.out.println("Bucket notification is set successfully");

        NotificationConfiguration minioClientBucketNotification =
                minioClient.getBucketNotification(
                        GetBucketNotificationArgs.builder().bucket("my-bucketname").build());
        System.out.println(minioClientBucketNotification);


        // 7. 策略配置
        StringBuilder builder = new StringBuilder();
        builder.append("{\n");
        builder.append("    \"Statement\": [\n");
        builder.append("        {\n");
        builder.append("            \"Action\": [\n");
        builder.append("                \"s3:GetBucketLocation\",\n");
        builder.append("                \"s3:ListBucket\"\n");
        builder.append("            ],\n");
        builder.append("            \"Effect\": \"Allow\",\n");
        builder.append("            \"Principal\": \"*\",\n");
        builder.append("            \"Resource\": \"arn:aws:s3:::my-bucketname\"\n");
        builder.append("        },\n");
        builder.append("        {\n");
        builder.append("            \"Action\": \"s3:GetObject\",\n");
        builder.append("            \"Effect\": \"Allow\",\n");
        builder.append("            \"Principal\": \"*\",\n");
        builder.append("            \"Resource\": \"arn:aws:s3:::my-bucketname/myobject*\"\n");
        builder.append("        }\n");
        builder.append("    ],\n");
        builder.append("    \"Version\": \"2012-10-17\"\n");
        builder.append("}\n");
        minioClient.setBucketPolicy(
                SetBucketPolicyArgs.builder().bucket("my-bucketname").config(builder.toString()).build());

    }
}
